package com.cheer.ba.view.activity;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.CircleOptions;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.Stroke;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;
import com.baidu.mapapi.search.poi.PoiDetailResult;
import com.baidu.mapapi.search.poi.PoiDetailSearchOption;
import com.baidu.mapapi.search.poi.PoiIndoorResult;
import com.baidu.mapapi.search.poi.PoiNearbySearchOption;
import com.baidu.mapapi.search.poi.PoiResult;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.baidu.mapapi.utils.OpenClientUtil;
import com.baidu.mapapi.utils.route.BaiduMapRoutePlan;
import com.baidu.mapapi.utils.route.RouteParaOption;
import com.cheer.ba.R;
import com.cheer.ba.app.App;
import com.cheer.ba.constant.IntentKey;
import com.cheer.ba.service.LocationService;
import com.cheer.ba.utils.LogUtils;
import com.cheer.ba.utils.ToastUtil;
import com.cheer.ba.utils.baidu.PoiOverlay;
import com.cheer.ba.view.base.BaseCommAty;
import com.cheer.ba.view.dialog.DialogUtils;

import java.util.List;

/**
 * 地图
 *
 * @author HQ
 *         created at 2017/5/17 0017 14:27
 */
public class BaiduMapAty extends BaseCommAty implements SensorEventListener, BaiduMap.OnMapLoadedCallback {

    //父布局
    RelativeLayout mRelaRoot;
    //地图控件
    private MapView mMapView;
    //导航加油站名称
    private TextView mTxtNaviOilName;
    //导航加油站地址
    private TextView mTxtNaviOilAddress;
    //弹出框popupWindow
    private PopupWindow mShowPop;

    // 定位相关
    private LocationService mLocationService;
    private MyLocationData locData;
    //传感器
    private SensorManager mSensorManager;

    private BaiduMap mBaiduMap;
    //周边检索
    private PoiSearch mPoiSearch = null;

    @Override
    protected boolean isSupportSwipeback() {
        return false;
    }


    @Override
    public View loadView(LayoutInflater inflater, View childView) {
        return super.loadView(inflater, inflater.inflate(R.layout.aty_baidu_map, null, false));
    }

    @Override
    public void initView() {
        setTitleText(getString(R.string.oil_navigation));
        init();
        initMap();
    }

    /**
     * 控件初始化
     */
    private void init() {
        mRelaRoot = (RelativeLayout) findViewById(R.id.id_map_root_view);
        // 地图初始化
        mMapView = (MapView) findViewById(R.id.id_baidu_map);

        findViewById(R.id.id_map_location).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 开始定位
                if (null != mLocationService) {
                    mLocationService.start();
                }
            }
        });

        View mView = getLayoutInflater().inflate(R.layout.popup_map_navi, null);
        mTxtNaviOilName = (TextView) mView.findViewById(R.id.id_navi_oil_name_txt);
        mTxtNaviOilAddress = (TextView) mView.findViewById(R.id.id_navi_oil_address_txt);
        mView.findViewById(R.id.id_diss_view).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (null != mShowPop) {
                    mShowPop.dismiss();
                    // 开始定位
                    if (null != mLocationService) {
                        mLocationService.start();
                    }
                }
            }
        });
        mView.findViewById(R.id.id_navi_rela).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //路线规划
                Intent intent = new Intent(aty, NaviMapAty.class);
                intent.putExtra(IntentKey.Location.KEY_START_LATITUDE, mCurrentLat);
                intent.putExtra(IntentKey.Location.KEY_START_LONGITUDE, mCurrentLon);
                intent.putExtra(IntentKey.Location.KEY_END_LATITUDE, mEndLat);
                intent.putExtra(IntentKey.Location.KEY_END_LONGITUDE, mEndLon);
                intent.putExtra(IntentKey.Location.KEY_OIL_NAME, mOilName);
                intent.putExtra(IntentKey.Location.KEY_OIL_ADDRESS, mEndAddress);
                showActivity(aty, intent);
            }
        });
        mView.findViewById(R.id.id_start_map_rela).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //调起百度地图周边检索
                startRoutePlanDriving();
            }
        });
        mShowPop = DialogUtils.initPopup(mView);
    }

    /**
     * 启动百度地图驾车路线规划
     */
    public void startRoutePlanDriving() {
        LatLng ptStart = new LatLng(mCurrentLat, mCurrentLon);
        LatLng ptEnd = new LatLng(mEndLat, mEndLon);
        // 构建 route搜索参数
        RouteParaOption para = new RouteParaOption().startPoint(ptStart).endPoint(ptEnd);
        try {
            BaiduMapRoutePlan.openBaiduMapDrivingRoute(para, this);
        } catch (Exception e) {
            e.printStackTrace();
            showDialog();
        }

    }

    /**
     * 提示未安装百度地图app或app版本过低
     */
    public void showDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("您尚未安装百度地图app或app版本过低，点击确认安装？");
        builder.setTitle("提示");
        builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                OpenClientUtil.getLatestBaiduMapApp(aty);
            }
        });

        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        builder.create().show();
    }

    /**
     * 初始化地图
     */
    private void initMap() {
        mBaiduMap = mMapView.getMap();
        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);
        // 开启地图加载成功监听
        mBaiduMap.setOnMapLoadedCallback(this);
    }

    /**
     * 地图加载成功回掉
     */
    @Override
    public void onMapLoaded() {
        initSearch();
        initLocation();
    }

    /**
     * 初始化搜索模块，注册搜索事件监听
     */
    private void initSearch() {
        mPoiSearch = PoiSearch.newInstance();
        mPoiSearch.setOnGetPoiSearchResultListener(new OnGetPoiSearchResultListener() {
            //查询结果回调
            @Override
            public void onGetPoiResult(PoiResult result) {
                LogUtils.LogD("Search", "111111111111111111111");
                if (null == result) {
                    return;
                }
                if (result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND || result.error == SearchResult.ERRORNO.AMBIGUOUS_KEYWORD || result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
                    ToastUtil.showToast("未找到附近中石油加油站");
                } else if (result.error == SearchResult.ERRORNO.ST_EN_TOO_NEAR) {
                    ToastUtil.showToast("目标距离太近");
                } else if (result.error == SearchResult.ERRORNO.PERMISSION_UNFINISHED) {
                    ToastUtil.showToast("授权未完成");
                } else if (result.error == SearchResult.ERRORNO.NO_ERROR) {
                    //检索成功
                    List<PoiInfo> pois = result.getAllPoi();
                    if (null != pois && !pois.isEmpty()) {
                        for (PoiInfo poi : pois) {
                            LogUtils.LogD("poi", poi.city + "--" + poi.address + "--" + poi.name + "---" + poi.location.latitude + "---" + poi.location.longitude);
                        }
                    }
                    mBaiduMap.clear();
                    PoiOverlay overlay = new MyPoiOverlay(mBaiduMap);
                    mBaiduMap.setOnMarkerClickListener(overlay);
                    overlay.setData(result);
                    overlay.addToMap();
                    overlay.zoomToSpan();
                    showNearbyArea(new LatLng(mCurrentLat, mCurrentLon), 0);
                    return;
                } else {
                    ToastUtil.showToast("查找油站失败");
                }
            }

            //详情查询结果回调
            @Override
            public void onGetPoiDetailResult(PoiDetailResult result) {
                LogUtils.LogD("Search", "22222222222222");
                if (null == result) {
                    return;
                }
                if (result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND || result.error == SearchResult.ERRORNO.AMBIGUOUS_KEYWORD || result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
                    ToastUtil.showToast("未找到附近中石油加油站");
                } else if (result.error == SearchResult.ERRORNO.ST_EN_TOO_NEAR) {
                    ToastUtil.showToast("目标距离太近");
                } else if (result.error == SearchResult.ERRORNO.PERMISSION_UNFINISHED) {
                    ToastUtil.showToast("授权未完成");
                } else if (result.error == SearchResult.ERRORNO.NO_ERROR) {
                    //结果返回正常
                    mEndLat = result.location.latitude;
                    mEndLon = result.location.longitude;
                    mOilName = result.getName();
                    mEndAddress = result.getAddress();

                    LogUtils.LogD("Search", mOilName + "--" + mEndLat + "--" + mEndLon + "--" + mEndAddress);

                    mTxtNaviOilName.setText(mOilName);
                    mTxtNaviOilAddress.setText(mEndAddress);

                    //弹出popup
                    DialogUtils.showDrawPop(mRelaRoot, aty);
                    // 停止定位
                    if (null != mLocationService) {
                        mLocationService.stop();
                    }
                } else {
                    ToastUtil.showToast("查找油站失败");
                }
            }

            @Override
            public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {

            }
        });
    }

    //绘制地图覆盖物
    private class MyPoiOverlay extends PoiOverlay {
        public MyPoiOverlay(BaiduMap baiduMap) {
            super(baiduMap);
        }

        @Override
        public boolean onPoiClick(int index) {
            super.onPoiClick(index);
            PoiInfo poi = getPoiResult().getAllPoi().get(index);
            mPoiSearch.searchPoiDetail((new PoiDetailSearchOption())
                    .poiUid(poi.uid));
            return true;
        }
    }

    /**
     * 对周边检索的范围进行绘制
     *
     * @param center
     * @param radius
     */
    public void showNearbyArea(LatLng center, int radius) {
        BitmapDescriptor centerBitmap = BitmapDescriptorFactory
                .fromResource(R.drawable.ic_map_arrow);
        MarkerOptions ooMarker = new MarkerOptions().position(center).icon(centerBitmap);
        mBaiduMap.addOverlay(ooMarker);
        OverlayOptions ooCircle = new CircleOptions().fillColor(0x7f0f00d3)
                .center(center).stroke(new Stroke(5, 0x7f0f00d3))
                .radius(radius);
        mBaiduMap.addOverlay(ooCircle);
    }

    /**
     * 初始化定位
     */
    private void initLocation() {
        //获得定位服务
        mLocationService = ((App) getApplication()).mLocationService;
        //获取locationservice实例，建议应用中只初始化1个location实例，然后使用，可以参考其他示例的activity，都是通过此种方式获取locationservice实例的
        mLocationService.registerListener(mListener);
        mLocationService.setLocationOption(mLocationService.getDefaultLocationClientOption());
        // 开始定位
        mLocationService.start();
    }

    /**
     * 定位SDK监听函数
     */
    public BDLocationListener mListener = new BDLocationListener() {
        @Override
        public void onReceiveLocation(BDLocation location) {
            // map view 销毁后不在处理新接收的位置
            if (location == null || mMapView == null) {
                return;
            }
            mCurrentLat = location.getLatitude();
            mCurrentLon = location.getLongitude();
            mStartAddress = location.getAddrStr();
            mCurrentAccracy = location.getRadius();
            locData = new MyLocationData.Builder()
                    .accuracy(mCurrentAccracy)
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(mCurrentDirection).latitude(mCurrentLat)
                    .longitude(mCurrentLon).build();
            mBaiduMap.setMyLocationData(locData);

            LatLng ll = new LatLng(mCurrentLat, mCurrentLon);
            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(ll).zoom(18.0f);
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));

            LogUtils.LogD("baidu---Location", mCurrentLat + "---" + mCurrentLon + "---" + mStartAddress);
            searchChinaOil();
        }

        public void onReceivePoi(BDLocation poiLocation) {
        }
    };

    /**
     * 范围检索-中国石油
     */
    private void searchChinaOil() {
        PoiNearbySearchOption mPoiNear = new PoiNearbySearchOption();
        mPoiNear.keyword("中石油加油站");
        mPoiNear.location(new LatLng(mCurrentLat, mCurrentLon));
        mPoiNear.radius(10000);
        mPoiSearch.searchNearby(mPoiNear);
    }

    @Override
    protected void onStart() {
        super.onStart();
        //获取传感器管理服务
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    }

    @Override
    protected void onResume() {
        mMapView.onResume();
        super.onResume();
        //为系统的方向传感器注册监听器
        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                SensorManager.SENSOR_DELAY_UI);
    }

    //记录最后一次x轴坐标的位置
    private Double lastX = 0.0;
    //记录当前地图所指方向
    private int mCurrentDirection = 0;
    //地图所在角度
    private float mCurrentAccracy;
    //当前位置纬度
    private double mCurrentLat = 0.0;
    //当前位置经度
    private double mCurrentLon = 0.0;
    //当前定位地址地址
    private String mStartAddress;
    //终点纬度
    private double mEndLat = 0.0;
    //终点经度
    private double mEndLon = 0.0;
    //终点地址
    private String mEndAddress;
    //油站名称
    private String mOilName;

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        double x = sensorEvent.values[SensorManager.DATA_X];
        if (Math.abs(x - lastX) > 1.0) {
            mCurrentDirection = (int) x;
            if (mCurrentLat > 0 && mCurrentLon > 0) {
                locData = new MyLocationData.Builder()
                        .accuracy(mCurrentAccracy)
                        // 此处设置开发者获取到的方向信息，顺时针0-360
                        .direction(mCurrentDirection).latitude(mCurrentLat)
                        .longitude(mCurrentLon).build();
                mBaiduMap.setMyLocationData(locData);
            }
        }
        lastX = x;
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }

    @Override
    protected void onPause() {
        mMapView.onPause();
        super.onPause();
    }

    @Override
    protected void onStop() {
        //取消注册传感器监听
        mSensorManager.unregisterListener(this);
        //注销监听
        mLocationService.unregisterListener(mListener);
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        //停止定位服务,退出时销毁定位
        mLocationService.stop();
        //注销搜索
        mPoiSearch.destroy();
        BaiduMapRoutePlan.finish(this);
        // 关闭定位图层
        mBaiduMap.setMyLocationEnabled(false);
        mMapView.onDestroy();
        mMapView = null;
        super.onDestroy();
    }
}
